<template>
  <div>
    <div v-if="colorDisabled" class="el-color-picker__mask"></div>
    <el-tabs v-model="activeTab" type="border-card">
      <el-tab-pane label="纯色" name="first">
        <picker-dropdown
          ref="dropdown"
          v-model="showPicker"
          :showPanelColor="showPanelColor"
          :color="color"
          :show-alpha="showAlpha"
          :predefine="predefine"
          :class="['el-color-picker__panel', popperClass || '']"
          @pick="confirmValue"
          @clear="clearValue">
        </picker-dropdown>
      </el-tab-pane>
      <el-tab-pane label="渐变色" name="second" v-if="isBackgroundColor">
        <PickerLinear
          ref="dropdown"
          :background-linear-gradient="linearGradient"
          :showPanelColor="showPanelColor"
          :color="color"
          :show-alpha="showAlpha"
          :predefine="predefine"
          :class="['el-color-picker__panel', popperClass || '']"
          @pick="confirmValue"
          @clear="clearValue"></PickerLinear>
      </el-tab-pane>
    </el-tabs>

  </div>

</template>

<script>
  import Color from './color';
  import PickerDropdown from './components/picker-dropdown.vue';
  import PickerLinear from './components/picker-linear.vue';
  import Clickoutside from 'element-ui/src/utils/clickoutside';
  import Emitter from 'element-ui/src/mixins/emitter';
  import {mapState} from "vuex";
  import {deepCopy, formatColor} from "@/utils";

  export default {
    name: 'LinearColorPicker',
    directives: {Clickoutside},
    components: {
      PickerDropdown, PickerLinear
    },
    mixins: [Emitter],
    inject: {
      elForm: {
        default: ''
      },
      elFormItem: {
        default: ''
      }
    },
    props: {
      //颜色值
      value: {
        type: String,
        default: ''
      },
      //渐变色
      backgroundColorObject: {
        type: Object,
        default: () => {
          return {}
        }
      },
      //是否为背景色
      isBackgroundColor: {
        type: Boolean,
        default: false
      },
      showAlpha: {
        type: Boolean,
        default: false
      },
      colorFormat: {
        type: String,
        default: 'rgb'
      },
      disabled: {
        type: Boolean,
        default: false
      },
      size: {
        type: String,
        default: ''
      },
      popperClass: {
        type: String,
        default: ''
      },
    },
    data() {
      const color = new Color({
        enableAlpha: this.showAlpha,
        format: this.colorFormat
      });
      return {
        color,
        showPicker: true,
        showPanelColor: false,
        predefine: [
          "#1A1A1A", "#333333", "#666666", "#999999", "#B3B3B3", "#CCCCCC", "#D3D3D3",
          "#F2F2F2", "#F7F7F7", "#FFFFFF", "#3779F0", "#2DC565", "#FCC140", "#F25644"
        ],
        activeTab: 'first',
        linearGradient: {}
      };
    },
    computed: {
      ...mapState({
        activeTheme: state => state.ide.activeTheme
      }),
      displayedColor() {
        if (!this.backgroundColorObject.backgroundColor && !this.showPanelColor) {
          return 'transparent';
        }
        return this.displayedRgb(this.color, this.showAlpha);
      },
      _elFormItemSize() {
        return (this.elFormItem || {}).elFormItemSize;
      },
      colorSize() {
        return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
      },
      colorDisabled() {
        return this.disabled || (this.elForm || {}).disabled;
      },
      formatColor() {
        return formatColor(this.backgroundColorObject.backgroundColor, this.activeTheme);
      }
    },
    watch: {
      value(val) {
        if (!val) {
          this.showPanelColor = false;
        } else if (val && val !== this.color.value) {
          this.color.fromString(val);
        }
      },
      backgroundColorObject: {
        deep: true,
        immediate: true,
        handler(val) {
          const {backgroundColor = '', linearGradient = {}} = val
          if (!val) {
            this.showPanelColor = false;
          }
          this.linearGradient = deepCopy(linearGradient)
          if (backgroundColor && backgroundColor !== this.color.value) {
            // this.color.fromString(val);
          }
          if (backgroundColor && backgroundColor.length > 0) {
            this.activeTab = 'first'
          }
          if (linearGradient.colors && linearGradient.colors.length > 0) {
            this.activeTab = 'second'
          }
        }

      },
      color: {
        deep: true,
        handler() {
          this.showPanelColor = true;
        }
      },
      displayedColor(val) {
        const value = this.isBackgroundColor ? this.backgroundColorObject.backgroundColor : this.value;
        if (!this.showPicker) return;
        const currentValueColor = new Color({
          enableAlpha: this.showAlpha,
          format: this.colorFormat
        });
        currentValueColor.fromString(value);
        const currentValueColorRgb = this.displayedRgb(currentValueColor, this.showAlpha);
        if (val !== currentValueColorRgb) {
          this.$emit('active-change', val);
        }
      }
    },
    mounted() {
      const value = this.isBackgroundColor ? this.backgroundColorObject.backgroundColor : this.value;
      if (value) {
        this.color.fromString(this.formatColor);
      }
      this.popperElm = this.$refs.dropdown.$el;
    },
    methods: {
      confirmValue(data) {
        let value = ''
        if (this.color.key.length > 0) {
          value = this.color.key;
        } else {
          value = this.color.value;
        }
        if (!this.isBackgroundColor) {
          //单纯颜色
          this.$emit('input', value);
          this.$emit('change', value);
          this.dispatch('ElFormItem', 'el.form.change', value);
        } else {
          let confirmData = {
            backgroundColor: '',
            linearGradient: {
              direction: 'right',
              colors: []
            },
          }
          //背景+渐变色
          if (data === 'backgroundColor') {
            //背景
            confirmData.linearGradient = {
              direction: 'right',
              colors: []
            }
            let value = ''
            if (this.color.key.length > 0) {
              value = this.color.key;
            } else {
              value = this.color.value;
            }
            confirmData.backgroundColor = value
            this.$emit('input', value);
            this.$emit('change', value);
            this.dispatch('ElFormItem', 'el.form.change', value);
          } else {
            //渐变色
            confirmData.backgroundColor = ''
            confirmData.linearGradient = data
          }
          this.$emit("confirmBgColor", confirmData);
        }
        this.showPicker = false;
        this.showPanelColor = false;
        this.$EventBus.$emit('popoverHide', false);
      },
      clearValue() {
        const value = this.isBackgroundColor ? this.backgroundColorObject.backgroundColor : this.value;
        if (value !== null) {
          this.dispatch('ElFormItem', 'el.form.change', null);
        }
        if (this.isBackgroundColor) {
          let confirmData = {
            backgroundColor: '',
            linearGradient: {
              direction: 'right',
              colors: []
            },
          }
          this.$emit("confirmBgColor", confirmData);
        } else {
          this.$emit('input', null);
          this.$emit('change', null);
        }
        this.showPanelColor = false;
        this.showPicker = false;
        this.resetColor();
        this.$EventBus.$emit('popoverHide', false);
      },
      hide() {
        this.showPicker = false;
        this.resetColor();
      },
      resetColor() {
        const value = this.isBackgroundColor ? this.backgroundColorObject.backgroundColor : this.value;
        this.$nextTick(_ => {
          if (value) {
            this.color.fromString(value);
          } else {
            this.showPanelColor = false;
          }
        });
      },
      displayedRgb(color, showAlpha) {
        if (!(color instanceof Color)) {
          throw Error('color should be instance of Color Class');
        }
        const {r, g, b} = color.toRgb();
        return showAlpha
          ? `rgba(${r}, ${g}, ${b}, ${color.get('alpha') / 100})`
          : `rgb(${r}, ${g}, ${b})`;
      }
    }
  };
</script>
<style scoped lang="less">

  /deep/ .el-popover {
    border: none !important;
    background: none !important;
    box-shadow: none !important;
  }

  /deep/ .el-tabs--border-card > .el-tabs__content {
    padding: 0;
  }

  .color-border {
    width: 28px;
    height: 28px;
    padding: 4px;
    border: 1px solid #e6e6e6;
    border-radius: 4px;
    background: transparent;

    .color-border-box {
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      border: 1px solid #999;
      background-image: url();

      .arrow {
        color: #fff;
        font-size: 16px;
      }
    }
  }
</style>
